﻿package examples;
import flash.display.Sprite;
import flash.Lib;
import fpc.controls.buttons.Button;
import fpc.containers.Panel;
import fpc.controls.text.Label;
import fpc.controls.text.TextArea;
import fpc.layouts.GridLayout;
import fpc.layouts.ILayout;
import fpc.layouts.ILayoutable;
import fpc.styles.skins.IScaledButtonSkin;
import fpc.styles.skins.ITextBackgroundSkin;
import fpc.styles.Style;
import fpc.utils.ClassFactory;
import fpc.utils.Herald;
import glam.skins.GlamPanel;
import glam.skins.GlamScaledButton;
import glam.skins.GlamTextBackground;

class Calculator extends CalculatorGui
{	
	public function new() 
	{
		super();
		
		_model = new Model();
		_model.heraldChange.addSimple(onModelChange);
		
		_controller = new Controller(_model);
		
		for (i in 0 ... 10)
		{
			_numericals[i].heraldClick.addSimple(
				callback(onNumericalClick, i)
			);
		}
		
		_btnClear.heraldClick.addSimple(
			_controller.clear
		);
		_btnPlus.heraldClick.addSimple(
			_controller.plus
		);
		_btnMinus.heraldClick.addSimple(
			_controller.minus
		);
		_btnMultiply.heraldClick.addSimple(
			_controller.multiply
		);
		_btnDivide.heraldClick.addSimple(
			_controller.divide
		);
		_btnCalculate.heraldClick.addSimple(
			_controller.calculate
		);
	}
	
	function xTrace(value:String)
	{
		trace(value);
	}
	
	var _model:Model;
	
	var _controller:Controller;
	
	function onNumericalClick(number:Int)
	{
		_model.string += number;
	}
	
	function onModelChange()
	{
		_display.text = _model.string;
	}
	
	public static function main()
	{	
		new Calculator().addTo(Lib.current);
	}
}

class Controller
{
	var _model:Model;
	
	public function new(model:Model)
	{
		_model = model;
		clear();
	}
	
	var _first:Float;
	
	var _second:Float;
	
	var _operation:String;
	
	public function plus()
	{
		_first = _model.number;
		_model.number = 0;
		_operation = '+';
	}
	
	public function minus()
	{
		_first = _model.number;
		_model.number = 0;
		_operation = '-';
	}
	
	public function multiply()
	{
		_first = _model.number;
		_model.number = 0;
		_operation = '*';
	}
	
	public function divide()
	{
		_first = _model.number;
		_model.number = 0;
		_operation = '/';
	}
	
	public function clear()
	{
		_first = Math.NaN;
		_first = Math.NaN;
		_model.number = 0;
	}
	
	public function calculate()
	{
		_second = _model.number;
		_model.number = switch(_operation)
		{
			case '+': _first + _second;
			case '-': _first - _second;
			case '*': _first * _second;
			case '/': _first / _second;
		}
	}
}

class Model
{
	public function new()
	{
		heraldChange = new Herald();
	}
	
	public var heraldChange(default, null):Herald<Void>;
	
	public var string(getString, setString):String;
	var _string:String;
	function getString()
	{
		return _string;
	}
	function setString(value)
	{
		_string = value;
		_number = Std.parseFloat(_string);
		heraldChange.dispatch(null);
		return _string;
	}
	
	public var number(getNumber, setNumber):Float;
	var _number:Float;
	function getNumber()
	{
		return _number;
	}
	function setNumber(value)
	{
		_number = value;
		_string = Std.string(value);
		heraldChange.dispatch(null);
		return _number;
	}
}

class CalculatorGui extends Panel<ILayout>
{
	var _display:TextArea;
	
	var _numericals:Array<Button>;
	
	var _btnDot:Button;
	
	var _btnPlus:Button;
	
	var _btnMinus:Button;
	
	var _btnMultiply:Button;
	
	var _btnDivide:Button;
	
	var _btnCalculate:Button;
	
	var _btnClear:Button;
	
	function new()
	{
		var layout = new GridLayout();
		super(layout);
			
		style = new Style()
			.setSkin(Button.SKIN_TYPE_BUTTON, new GlamScaledButton())
			.setSkin(TextArea.SKIN_TYPE_TEXT_AREA, new GlamTextBackground())
			.setSkin(Panel.SKIN_TYPE_PANEL, new GlamPanel());
		
		_btnCalculate = new Button('=');
		_btnCalculate.percentsWidth = 100;
		_btnCalculate.percentsHeight = 100;
		_btnPlus = new Button('+');
		_btnPlus.percentsWidth = 100;
		_btnMinus = new Button('-');
		_btnMinus.percentsWidth = 100;
		_btnMultiply = new Button('*');
		_btnMultiply.percentsWidth = 100;
		_btnDivide = new Button('/');
		_btnDivide.percentsWidth = 100;
		_btnDot = new Button('.');
		_btnDot.percentsWidth = 100;
		_btnClear = new Button('C');
		_btnClear.percentsWidth = 100;
		_btnClear.percentsHeight = 100;
		_btnCalculate.enabled = false;
		
		_numericals = [];
		for (i in 0 ... 10)
		{
			var button = new Button(Std.string(i));
			button.percentsWidth = 100;
			_numericals[i] = button;
		}
		
		var row = 0;
		
		_display = new TextArea();
		_display.text = '0';
		_display.percentsWidth = 100;
		_display.selectable = true;
		layout.add(_display, row, 0, 1, 5);
		
		row++;
		
		layout.add(_numericals[1], row, 0);
		layout.add(_numericals[2], row, 1);
		layout.add(_numericals[3], row, 2);
		layout.add(_btnPlus, row, 3);
		layout.add(_btnClear, row, 4, 2);
		
		row++;
		
		layout.add(_numericals[4], row, 0);
		layout.add(_numericals[5], row, 1);
		layout.add(_numericals[6], row, 2);
		layout.add(_btnMinus, row, 3);
		
		row++;
		
		layout.add(_numericals[7], row, 0);
		layout.add(_numericals[8], row, 1);
		layout.add(_numericals[9], row, 2);
		layout.add(_btnMultiply, row, 3);
		layout.add(_btnCalculate, row, 4, 2);
		
		row++;
		
		layout.add(_numericals[0], row, 0, 1, 2);
		layout.add(_btnDivide, row, 3);
		layout.add(_btnDot, row, 2);
		
		layout.autoSize = false;
		width = 200;
	}
}